package com.kilomob.grady.spring;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

import com.kilomob.grady.client.DefaultInvoker;
import com.kilomob.grady.proxy.InvokerInvocationHandler;
import com.kilomob.grady.proxy.Proxy;
import com.kilomob.grady.rpc.Invoker;

/**
 * 
 * reference解析
 * 
 *   
 * @author zhouzhixiang  
 * @date 2016年12月31日
 * @since 1.0
 */
public class ReferenceBean<T> implements FactoryBean<T>,InitializingBean, DisposableBean {
    
    private Class<?>             interfaceClass;
    private transient volatile boolean initialized;
    private transient volatile T ref;
    private String interfaceName;
    private String clientId;
    private String protocol;
    private String id;
    private int timeout;
    private boolean oneway;
    private boolean async;
    
    
    
    public String getInterface() {
        return interfaceName;
    }

    public void setInterface(String interfaceName) {
        this.interfaceName = interfaceName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public void destroy() throws Exception {
    }
    
    @SuppressWarnings({"unchecked","rawtypes"})
    public T getObject() throws Exception {
        if(initialized){
            return ref;
        }
        Invoker invoker =  new DefaultInvoker(this.getClass().getClassLoader().loadClass(interfaceName),clientId);
        invoker.setAsync(async);
        invoker.setOneway(oneway);
        invoker.setTimeout(timeout);
        ref = (T) Proxy.getProxy(getObjectType()).newInstance(new InvokerInvocationHandler(invoker ));
        initialized = true;
        return ref;
//        return MessageSendProxy.execute(getObjectType());
    }
    
    public Class<?> getObjectType() {
        
        if (interfaceClass != null) {
            return interfaceClass;
        }
        try {
            if (interfaceName != null && interfaceName.length() > 0) {
                this.interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                    .getContextClassLoader());
            }
        } catch (ClassNotFoundException t) {
            throw new IllegalStateException(t.getMessage(), t);
        }
        return interfaceClass;
    }

    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
    

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public boolean isOneway() {
        return oneway;
    }

    public void setOneway(boolean oneway) {
        this.oneway = oneway;
    }

    public boolean isAsync() {
        return async;
    }

    public void setAsync(boolean async) {
        this.async = async;
    }
    
}
